package com.sunwhite.herostore.common.async;

import com.sunwhite.herostore.common.MainThreadProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class AsyncOperationProcessor {
    /**
     * 日志对象
     */
    private static  final Logger log= LoggerFactory.getLogger(AsyncOperationProcessor.class);

    /**
     * 单例对象
     */
    private static final AsyncOperationProcessor asyncOperationProcessor=new AsyncOperationProcessor();

    /**
     * 多线程组
     */
    private final ExecutorService[] executorServices=new ExecutorService[8];

    /**
     * 私有化默认构造器
     */
    private AsyncOperationProcessor(){
        log.info("初始化asyncOperationProcessor线程池=======>");
        for (int i = 0; i < executorServices.length; i++) {
            String threadName = "AsyncOperationProcessor" + i;
            //创建单线程服务
            executorServices[i]=Executors.newSingleThreadExecutor((runnable)->{
                Thread thread = new Thread(runnable);
                thread.setName(threadName);
                return thread;
            });
        }
    }

    /**
     * 获取单例对象
     * @return
     */
    public static AsyncOperationProcessor getInstance(){
        return asyncOperationProcessor;
    }

    /**
     * 分配相应线程
     * 执行异步操作
     * @param asyncOperation 异步操作接口的实现
     */
    public void process(AsyncOperation asyncOperation){
        if (null==asyncOperation){
            return;
        }

        //根据绑定ID 分配线程
        int bingId = Math.abs(asyncOperation.getBingId());
        int esIndex = bingId % executorServices.length;
        if (esIndex<0||esIndex>=executorServices.length){
            return;
        }

        //分配相应的单线程线程池执行异步操作

        executorServices[esIndex].submit(()->{
            //异步操作处理器执行异步操作
            try {
                //执行异步操作
                asyncOperation.doAsync();

                //回到主消息处理器 执行完成逻辑
                MainThreadProcessor.getInstance().process(asyncOperation::doFinish);
            } catch (Exception e) {
               log.error(e.getMessage(),e);
            }
        });
    }
}
